package com.huluobo.jetpackkotlindemo.paging

import android.content.Context
import android.net.ConnectivityManager
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import com.huluobo.jetpackkotlindemo.MyApplication
import com.huluobo.jetpackkotlindemo.paging.db.AppDatabase
import com.huluobo.jetpackkotlindemo.paging.db.RepoEntity

/**
 * Created by lc on 2022/12/21.
 * 因为RemoteMediator 远程调度器是实验性api,所有实现RemoteMediator的类必须要添加一个注解
 * @OptIn(ExperimentalPagingApi::class),这个注解需要在gradle中添加一个行命令
 * kotlinOptions {
 * freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn"]
 * }
 */
@OptIn(ExperimentalPagingApi::class)
class RepoMediator(val api: ApiService, val db: AppDatabase, val context: Context) :
    RemoteMediator<Int, RepoEntity>() {
    override suspend fun load(
        loadType: LoadType,
        state: PagingState<Int, RepoEntity>
    ): MediatorResult {
        val repoDao = db.repoDao()

        //确定Paging翻页的key值
        val pageKey = when (loadType) {
            //首次访问,或者调用PageDataAdapter.refresh的时候
            LoadType.REFRESH -> null
            //在当前加载的数据集合的开头加载数据时
            LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
            //下拉加载更多时
            LoadType.APPEND -> {
                val lastItem = state.lastItemOrNull()
                    ?: return MediatorResult.Success(endOfPaginationReached = true)
                lastItem.page
            }
        }

        //无网络则加载本地数据
        if (!isConnectedNetWork()) {
            return MediatorResult.Success(endOfPaginationReached = true)
        }

        //有网情况下网络分页数据
        val page = pageKey ?: 0
        val pageSize = Repository.PAGE_SIZE
        val result = api.searRepos(page, pageSize).items
        val endOfPaginationReached = result.isEmpty()
        val items = result.map {
            RepoEntity(
                id = it.id,
                name = it.name,
                description = it.description,
                starCount = it.starCount,
                page = page + 1
            )
        }

        //插入数据库中
        if (loadType == LoadType.REFRESH) {
            repoDao.clear()
        }
        repoDao.insert(items)
        return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
    }

    //判断当前是否有网络连接
    private fun isConnectedNetWork(): Boolean {
        val connectManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val activeNetWorInfo = connectManager.activeNetworkInfo
        return activeNetWorInfo != null && activeNetWorInfo.isConnected
    }
}